CloudFormation으로 EC2 인스턴스 구축해 보기
안녕하세요 클래스메소드 김재욱(Kim Jaewook) 입니다. 이번에는 CloudFormation으로 EC2 인스턴스를 구축해 보는 과정을 정리해 봤습니다.
EC2를 구축하기에 앞서, VPC, 서브넷과 같은 네트워크가 구성 되어 있어야 합니다. CloudFormation으로 네트워크를 구성하는 방법은 아래 블로그를 참고해 주세요.
CloudFormation Output
이번에는 하나의 CloudFormation 스택에서 모든 작업 처리 하는 것이 아니기 때문에 다른 스택으로 값을 넘겨줄 필요가 있습니다. 값을 넘겨주기 위해서는「Outputs:」를 사용합니다.
#------------------------------------------------------------------- #OutPut #------------------------------------------------------------------- Outputs: # VPC VPC: Value: !Ref VPC Export: Name: !Sub "test-vpc" VPCCIDR: Value: !Ref VPCCIDR Export: Name: !Sub "test-vpc-cidr" # Subnet PublicSubnetA: Value: !Ref PublicSubnetA Export: Name: !Sub "test-front-subnet-1a" PublicSubnetACIDR: Value: !Ref PublicSubnetACIDR Export: Name: !Sub "test-front-subnet-1a-cidr" PublicSubnetC: Value: !Ref PublicSubnetC Export: Name: !Sub "test-front-subnet-1c" PublicSubnetCCIDR: Value: !Ref PublicSubnetCCIDR Export: Name: !Sub "test-front-subnet-1c-cidr" PrivateSubnetA: Value: !Ref PrivateSubnetA Export: Name: !Sub "test-application-subnet-1a" PrivateSubnetACIDR: Value: !Ref PrivateSubnetACIDR Export: Name: !Sub "test-application-subnet-1a-cidr" PrivateSubnetC: Value: !Ref PrivateSubnetC Export: Name: !Sub "test-application-subnet-1c" PrivateSubnetCCIDR: Value: !Ref PrivateSubnetCCIDR Export: Name: !Sub "test-application-subnet-1c-cidr" # Route FRONTRTB: Value: !Ref FRONTRTB Export: Name: !Sub "test-front-rtb" APPRTB1A: Value: !Ref APPRTB1A Export: Name: !Sub "test-application-rtb-1a" APPRTB1C: Value: !Ref APPRTB1C Export: Name: !Sub "test-application-rtb-1c"
먼저 파라미터에는 EC2에 접속하기 위한 키 페어 값을 입력합니다.
CloudFormation 내에서 키 페어를 생성할 수는 없기 때문에 콘솔 환경으로 들어가서 2개의 키 페어를 생성합니다. 편의상 키 페어 이름을 파라미터의 디폴트 값과 동일하게 적었지만 실제로 사용할 때는 디폴트 이름과 다른 이름을 사용할 필요가 있습니다.
파라미터 생성
AWSTemplateFormatVersion: "2010-09-09" Description: Create EC2, RDS Metadata: "AWS::CloudFormation::Interface": ParameterGroups: - Label: default: "EC2 Configuration" Parameters: - BastionEC2KeyPair - AppEC2KeyPair ParameterLabels: BastionEC2KeyPair: default: "BastionEC2KeyPair" AppEC2KeyPair: default: "AppEC2KeyPair" # ------------------------------------------------------------# # Input Parameters # ------------------------------------------------------------# Parameters: BastionEC2KeyPair: Type: String Default: "BastionEC2KeyPair" AppEC2KeyPair: Type: String Default: "AppEC2KeyPair"
보안 그룹 생성
# ------------------------------------------------------------# # Create Security Groups # ------------------------------------------------------------# Resources: FrontBastionSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: "test-front-bastion-sg" GroupName: test-front-bastion-sg SecurityGroupIngress: IpProtocol: tcp FromPort : 22 ToPort : 22 CidrIp: 0.0.0.0 VpcId: { "Fn::ImportValue": !Sub "test-vpc" } Tags: - Key: "Name" Value: test-front-bastion-sg APPSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: "test-app-sg" GroupName: test-app-sg SecurityGroupIngress: - IpProtocol: tcp FromPort : 22 ToPort : 22 SourceSecurityGroupId: !GetAtt FrontBastionSecurityGroup.GroupId VpcId: { "Fn::ImportValue": !Sub "test-vpc" } Tags: - Key: "Name" Value: test-app-sg
테스트용이기 때문에 test-front-bastion-sg에서 0.0.0.0으로 아이피를 뚫어놨지만, 실제 사용할 때는 파라미터에서 자신의 아이피를 입력 받아서 넣는 편이 좋습니다.
EC2 인스턴스 생성
# ------------------------------------------------------------# # Create EC2 Instance # ------------------------------------------------------------# # Bastion EC2 BastionEC2: Type: AWS::EC2::Instance Properties: ImageId: ami-0f66bf23ed74d9284 InstanceType: t3.micro KeyName: !Ref BastionEC2KeyPair DisableApiTermination: true BlockDeviceMappings: - DeviceName: "/dev/xvda" Ebs: VolumeType: "gp2" DeleteOnTermination: "true" VolumeSize: "8" SecurityGroupIds: - !Ref FrontBastionSecurityGroup SubnetId: { "Fn::ImportValue": !Sub "test-front-subnet-1a" } Tags: - Key: "Name" Value: test-front-bastion # test-app-1a AppEC2: Type: AWS::EC2::Instance Properties: ImageId: ami-0f66bf23ed74d9284 InstanceType: t3.micro KeyName: !Ref AppEC2KeyPair DisableApiTermination: true BlockDeviceMappings: - DeviceName: "/dev/xvda" Ebs: VolumeType: "gp2" DeleteOnTermination: "true" VolumeSize: "50" SecurityGroupIds: - !Ref APPSecurityGroup SubnetId: { "Fn::ImportValue": !Sub "test-application-subnet-1a" } Tags: - Key: "Name" Value: test-app-1a
Public Subnet에서 발판 서버를 만들고, Private Subnet에는 외부에서 접속이 불가능한 EC2 서버 한대를 구축 했습니다.
접속 테스트
-
ssh -i "BastionEC2KeyPair.pem" [email protected]
해당 명령어로 접속해 보면 정상적으로 발판 서버에 접속한 것을 확인할 수 있습니다.
- scp -i /BastionEC2KeyPair.pem /AppEC2KeyPair.pem [email protected]:~
- ssh -i "AppEC2KeyPair.pem" [email protected]
이어서 scp 명령어를 사용해서 발판 서버로 키 페어를 업로드 하고 ssh로 접속해 보면 프라이빗 EC2에도 문제 없이 접속 되는 것을 확인할 수 있습니다.
콘솔 환경에서 EC2 환경에 들어가보면 CloudFormation으로 생성한 EC2 인스턴스를 확인할 수 있습니다.